void reduce_hsn_core_frequency()
{
	volatile unsigned *base = (volatile unsigned *)0x8c000040;

	/* Specific for this application */
	/* HSN: PLL/16 */
	//*base |= 0x1000;
	//osFastPause(1000);
	/* Core 3: PLL/4 : L1 buffers */
	//*base |= 0x0500;
	//osFastPause(1000);
	/* Core 2: PLL/4 : TX IQ Buffers in L1 and PSD */
	*base |= 0x0050;
	osFastPause(1000);
	/* Core 1: PLL/2 */
	//*base |= 0x0004;
	//osFastPause(1000);

	/* Core 2 and 3 DSP should be clock gated */
}

void shutdown3500_peripherals()
{
	volatile unsigned *sdc_base = (volatile unsigned *)0x88007000;

	/** Bring up the peripherals **/
	*sdc_base = 0xFFFF;
	osFastPause(1000);

	/** Reset the peripherals **/
	*sdc_base = 0;
	osFastPause(1000);

	/** disable clocks **/
	*(sdc_base+4) = 0;
	*(sdc_base+5) = 0;
}

void shutdown3500_core2()
{
	volatile unsigned *dpmu_base = (volatile unsigned*)(0x8C000000+0x34);

	/** Reset **/
	*dpmu_base &= 0x3F7;
	osFastPause(1000);

	/** DSP 2**/
	*dpmu_base &= 0x3DF;
	osFastPause(1000);

	/** Core **/
	//*dpmu_base &= 0x3EF;
	//osFastPause(1000);

	/** DSP is isolated **/
	*dpmu_base &= 0x3FB;
	osFastPause(1000);

	/** Weak Power Control **/
	*dpmu_base &= 0x3FD;
	osFastPause(1000);

	/** Strong Power Control **/
	*dpmu_base &= 0x3FE;
	osFastPause(1000);
}

void shutdown3500_core3()
{
	volatile unsigned *dpmu_base = (volatile unsigned*)(0x8C000000+0x38);

	/** Reset **/
	*dpmu_base &= 0x3F7;
	osFastPause(1000);

	/** DSP 2**/
	*dpmu_base &= 0x3DF;
	osFastPause(1000);

	/** Clock gate DSP+DMU:Core **/
	*dpmu_base &= 0x3EF;
	osFastPause(1000);

	/** DSP is isolated **/
	*dpmu_base &= 0x3FB;
	osFastPause(1000);

	/** Weak Power Control **/
	*dpmu_base &= 0x3FD;
	osFastPause(1000);

	/** Strong Power Control **/
	*dpmu_base &= 0x3FE;
	osFastPause(1000);
}

void shutdown3500_arm9()
{
	volatile unsigned *dpmu_base = (volatile unsigned*)(0x8C000000+0x3C);

	/** Reset **/
	*dpmu_base &= 0x3F7;
	osFastPause(1000);

	/** ARM is isolated **/
	*dpmu_base &= 0x3FB;
	osFastPause(1000);

	/** Weak Power Control **/
	*dpmu_base &= 0x3FD;
	osFastPause(1000);

	/** Strong Power Control **/
	*dpmu_base &= 0x3FE;
	osFastPause(1000);
}

void
do_power_savings()
{
	/** Shutdown core2 **/
    shutdown3500_core2();
    osFastPause(10000);

    /** Shutdown core3 **/
    shutdown3500_core3();
    osFastPause(10000);

    /** Shutdown ARM **/
    shutdown3500_arm9();
    osFastPause(10000);

    /** Shutdown peripherals **/
    shutdown3500_peripherals();
    osFastPause(10000);

    reduce_hsn_core_frequency();
    osFastPause(10000);
}
